package com.agile.leetcode.hot.easy;

/**
 * 给定一个整数数组 nums ，找到一个具有最大和的连续子数组（子数组最少包含一个元素），返回其最大和。
 * <p>
 *  
 * <p>
 * 示例 1：
 * <p>
 * 输入：nums = [-2,1,-3,4,-1,2,1,-5,4]
 * 输出：6
 * 解释：连续子数组 [4,-1,2,1] 的和最大，为 6 。
 * 示例 2：
 * <p>
 * 输入：nums = [1]
 * 输出：1
 * 示例 3：
 * <p>
 * 输入：nums = [0]
 * 输出：0
 * 示例 4：
 * <p>
 * 输入：nums = [-1]
 * 输出：-1
 * 示例 5：
 * <p>
 * 输入：nums = [-100000]
 * 输出：-100000
 * <p>
 * 来源：力扣（LeetCode）
 * 链接：https://leetcode-cn.com/problems/maximum-subarray
 * 著作权归领扣网络所有。商业转载请联系官方授权，非商业转载请注明出处。
 *
 * @Author:ChenZhangKun
 * @Date: 2021/6/4 9:21
 */
public class MaxSumOfSubArray {
    public static void main(String[] args) {
        int[] nums = {-2, -1};
        MaxSumOfSubArray sum = new MaxSumOfSubArray();
        System.out.println(sum.maxSubMax(nums));
    }

    /**
     * dp规划求子数组和的最大值
     *
     * @param nums
     * @return
     */
    public int maxSubArray(int[] nums) {
        // 拿到数组长度
        int length = nums.length;
        // 创建dp数组
        int[] dp = new int[length];
        dp[0] = nums[0];
        // 遍历
        for (int i = 1; i < nums.length; i++) {
            // 状态转移方程
            if (dp[i - 1] > 0) {
                dp[i] = dp[i - 1] + nums[i];
            } else {
                dp[i] = nums[i];
            }
        }
        // 拿到最大值
        int max = Integer.MIN_VALUE;
        for (int i = 0; i < dp.length; i++) {
            if (dp[i] > max) {
                max = dp[i];
            }
        }
        return max;
    }

    public int maxSubMax(int[] arr) {
        // 创建dp数组
        int[] dp = new int[arr.length];
        // 初始化
        dp[0] = arr[0];
        // 遍历
        for (int i = 1; i < arr.length; i++) {
            if (arr[i - 1] > 0) {
                // 与
                dp[i] = arr[i] + dp[i - 1];
            } else {
                dp[i] = arr[i];
            }
        }
        // 拿到最大值
        int temp = Integer.MIN_VALUE;
        for (int i : dp) {
            if (i > temp) {
                temp = i;
            }
        }
        return temp;
    }
}
